package cn.clx.ymcc.consumer;

import cn.clx.ymcc.domain.CourseOrder;
import cn.clx.ymcc.dto.KillPreOrderParamsDto;
import cn.clx.ymcc.service.ICourseOrderService;
import cn.clx.ymcc.util.AssertUtil;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;

/**
 *  pay支付，mq发送延迟消息，超时这里消费消息---修改订单状态
 */
@Slf4j
@Component
@RocketMQMessageListener(topic = "pay-timeout-topic",
        selectorExpression="pay-timeout-tags"	//tags
                ,consumerGroup = "service-order-to-order-paytimeout-consumer",
        messageModel = MessageModel.BROADCASTING)
public class PayTimeOutConsumer implements RocketMQListener<MessageExt> {

    @Autowired
    private ICourseOrderService courseOrderService;
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 订单超时未支付，设置订单状态
     * 消费消息报错，意味着消费失败，从新就如队列进行消费，直到mq自动清除 ，或者消费成功未知
     * @param message
     */
    @Override
    @Transactional
    public void onMessage(MessageExt message) {
        log.info("执行了order微服务的延迟mq消息");
        String orderno = new String(message.getBody(), StandardCharsets.UTF_8);
        CourseOrder order = courseOrderService.findOrderByOrderNo(orderno);
        AssertUtil.isNotNull(order,"课程订单异常");

        //判断 订单是否为未支付
        Integer statusOrder = order.getStatusOrder();
        if(statusOrder.intValue()!=CourseOrder.STATE_PAY_SUCCESS.intValue()){
            order.setStatusOrder(CourseOrder.STATE_CANCEL);
            courseOrderService.updateById(order);

        }
        //若是成功支付，会删除redis中的预存订单，所以这里查不到
        KillPreOrderParamsDto dto =(KillPreOrderParamsDto) redisTemplate.opsForValue().get(orderno);
        if (dto!=null){
            log.info("进入了超时未支付，删除redis预存订单，还库存");
            //支付超时还库存
            String key = dto.getActivityId()+":"+dto.getKillCourseId();
            RSemaphore semaphore = redissonClient.getSemaphore(key);
            //还库存
            semaphore.release(1);
            //semaphore.trySetPermits(1);
            //删除预存订单
            redisTemplate.delete(dto.getOrderNo());
        }
    }
}